package com.db.hashmap;

import java.nio.ByteBuffer;
import java.util.*;

/**
 * @author Alexander Kotov (kotov.alex.22@gmail.com)
 */
public class SpeedTest {

    private static final int ELEMENTS_COUNT = 1000000;
    private static final int ITERATIONS = 1000;
    private final ByteBuffer byteBuffer = ByteBuffer.allocate(ELEMENTS_COUNT * 16);

    private void run() {

        ByteBufferHashMap byteBufferHashMap = new ByteBufferHashMap(byteBuffer);
        HashMap<Integer, Integer> hashMap = new HashMap<Integer, Integer>();

        Integer[] randomKeyArray = new Integer[ELEMENTS_COUNT];
        Integer[] randomValueArray = new Integer[ELEMENTS_COUNT];
        Integer[] randomKeyToGetArray = new Integer[ITERATIONS];

        for (int i = 0; i != ELEMENTS_COUNT; ++i) {
            randomKeyArray[i] = (int)(Math.random() * (Integer.MAX_VALUE));
            randomValueArray[i] = (int)(Math.random() * (Integer.MAX_VALUE));
            byteBufferHashMap.put(randomKeyArray[i], randomValueArray[i]);
            hashMap.put(randomKeyArray[i], randomValueArray[i]);
        }

        for (int i = 0; i != ITERATIONS; ++i) {
            randomKeyToGetArray[i] = randomKeyArray[(int)(Math.random() * (randomKeyArray.length))];
        }

        //Get ByteBufferHashMap
        long start = System.nanoTime();

        long res = 0;
        for (int i = 0; i != ITERATIONS; ++i) {
            res += byteBufferHashMap.get(randomKeyToGetArray[i]);
        }

        long time = (System.nanoTime() - start) / ITERATIONS;

        System.out.println(res);
        System.out.println("ByteBufferHashMap get: " + time + " nanosec");
        System.out.println("================================");

        //Get HashMap
        start = System.nanoTime();

        for (int i = 0; i != ITERATIONS; ++i) {
            res += hashMap.get(randomKeyToGetArray[i]);
        }

        time = (System.nanoTime() - start) / ITERATIONS;

        System.out.println(res);
        System.out.println("HashMap get: " + time + " nanosec");
        System.out.println("================================");

        hashMap.clear();
        byteBufferHashMap.clear();

        //Put ByteBufferHashMap
        start = System.nanoTime();

        for (int i = 0; i != ELEMENTS_COUNT; ++i) {
            byteBufferHashMap.put(randomKeyArray[i], randomValueArray[i]);
        }

        time = (System.nanoTime() - start) / ELEMENTS_COUNT;

        System.out.println(byteBufferHashMap.hashCode());
        System.out.println("ByteBufferHashMap put: " + time + " nanosec");
        System.out.println("================================");

        //Put HashMap
        start = System.nanoTime();

        for (int i = 0; i != ELEMENTS_COUNT; ++i) {
            hashMap.put(randomKeyArray[i], randomValueArray[i]);
        }

        time = (System.nanoTime() - start) / ELEMENTS_COUNT;

        System.out.println(hashMap.hashCode());
        System.out.println("HashMap put: " + time + " nanosec");
        System.out.println("================================");

    }

    public static void main(String[] args) {
        SpeedTest speedTest = new SpeedTest();
        speedTest.run();
    }
}
